﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static M3U8下载神器.Broadcast;

namespace M3U8下载神器
{
    public partial class BatchDownloadForm : Form
    {
        List<string> Lines { set; get; } = new List<string>();
        string Dir { set; get; }
        Listener listener;
        System.Timers.Timer timersTimer;

        public BatchDownloadForm()
        {
            InitializeComponent();
            listener = (o, t, code, msg) =>
            {
                if (o is DownloadForm && t == this && msg + "" == "closed")
                {
                    if (Lines.Count > 0)
                    {
                        var line = Lines[0];
                        Lines.RemoveAt(0);
                        Download(line, Dir);
                    }
                }
                UpdateUI();
            };
            Program.Broadcast.Add(listener);
            FormClosing += (o, e) =>
            {
                Program.Broadcast.Remove(listener);
                timersTimer?.Stop();
            };
            RefreshDownload();
            InitGrid();

        }
        private void InitGrid()
        {
            dataGridView1.Columns.Add("名称", "名称");
            dataGridView1.Columns.Add("链接", "链接");
            dataGridView1.Columns.Add("是否完成", "是否完成");
        }
        private void UpdateUI()
        {
            this.Invoke(new Action(() =>
            {
                this.Text = "正在下载，剩余:" + Lines.Count;
            }));
        }
        private void RefreshDownload()
        {
            timersTimer = new System.Timers.Timer();
            timersTimer.Enabled = false;
            timersTimer.Interval = 1000 * 120;
            timersTimer.SynchronizingObject = this;
            timersTimer.Elapsed += (o, e) =>
            {
                foreach (var form in Application.OpenForms)
                {
                    var df = form as DownloadForm;
                    if (df != null)
                    {
                        df.RefreshDownload();
                    }
                }
                UpdateUI();
            };
            timersTimer.Start();

        }
        public M3U8Package GetM3U8Package(string url, string savePath)
        {
            try
            {
                for (int try_layers = 0; try_layers < 5; try_layers++)
                {
                    string m3u8 = SimpleDownloader.Download2(url);
                    if (m3u8 != null)
                    {
                        var package = M3U8Package.Parse(url, m3u8);
                        if (package != null)
                        {
                            if (package.StreamInfos.Count > 0)
                            {
                                var streamPath = package.StreamInfos[0];
                                url = streamPath.ToLower().StartsWith("http") ? streamPath : (package.Host + streamPath);
                                continue;
                            }
                            package.SavePath = savePath;
                            return package;
                        }
                    }
                }

            }
            catch (Exception)
            {

            }
            return null;
        }
        public string ReplaceBadCharOfFileName(string fileName)
        {
            string str = fileName;
            str = str.Replace("\\", string.Empty);
            str = str.Replace("/", string.Empty);
            str = str.Replace(":", string.Empty);
            str = str.Replace("*", string.Empty);
            str = str.Replace("?", string.Empty);
            str = str.Replace("\"", string.Empty);
            str = str.Replace("<", string.Empty);
            str = str.Replace(">", string.Empty);
            str = str.Replace("|", string.Empty);
            //str = str.Replace(" ", string.Empty);    //前面的替换会产生空格,最后将其一并替换掉
            return str;
        }
        public void Download(string line, string dir, DownloadForm downloadForm = null)
        {
            var ss = line.Split('\t', '|');
            var name = ss[0];
            var url = ss[1];
            var package = GetM3U8Package(url, dir + '\\' + ReplaceBadCharOfFileName(name) + ".ts");
            if (package != null && package.Begin())
            {
                Invoke(new Action(() =>
                {
                    if (downloadForm == null)
                    {
                        downloadForm = new DownloadForm();
                        downloadForm.FinishAction += () =>
                        {
                            Program.Broadcast.SendMsg(downloadForm, this, 0, "closed");
                            Program.Broadcast.SendMsg(downloadForm, "download_log", 0, name + '\t' + url);
                        };
                    }
                    downloadForm.Build(package);
                    downloadForm.Show();
                    downloadForm.Start();
                }));
                Program.Broadcast.SendMsg(this, null, 1, "create");
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var lines = textBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            textBox1.Text = "";
            Lines.AddRange(lines);
            Dir = textBox2.Text;
            if (Lines.Count == 0) return;

            button1.Enabled = false;
            textBox2.ReadOnly = true;

            int free = 8 - Application.OpenForms.Count;

            ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
            {

                for (; free > 0; free--)
                {
                    if (Lines.Count > 0)
                    {
                        var line = Lines[0];
                        Lines.RemoveAt(0);
                        Download(line, Dir);
                    }
                }
            }));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var lines = textBox1.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            textBox1.Text = "";
            Lines.AddRange(lines);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
            {
                if (Lines.Count > 0)
                {
                    var line = Lines[0];
                    Lines.RemoveAt(0);
                    Download(line, Dir);
                }
            }));
        }
    }
}
